const http = require('http');
const WebSocket = require('ws');

const HOST = '127.0.0.1';
const PORT = 3000;
const MOBILE = '17091271111';
const PWD_HASH = 'e10adc3949ba59abbe56e057f20f883e';

function httpReq(path, method = 'GET', data = null) {
    return new Promise((resolve, reject) => {
        const opt = { hostname: HOST, port: PORT, path, method, headers: { 'Content-Type': 'application/json' } };
        const req = http.request(opt, res => {
            let body = '';
            res.on('data', c => body += c);
            res.on('end', () => { try { resolve(JSON.parse(body)); } catch { resolve({}); } });
        });
        req.on('error', reject);
        if (data) req.write(JSON.stringify(data));
        req.end();
    });
}

async function main() {
    console.log('🔐 登录...');
    // 先尝试使用已存在账号登录（md5）
    const tryLogin = async (pwdValue) => {
        try {
            const res = await httpReq('/user-service/user/login', 'POST', { mobile: MOBILE, pwd: pwdValue });
            return res || {};
        } catch { return {}; }
    };

    // 注册一次以防账号不存在
    await httpReq('/user-service/user/register', 'POST', { mobile: MOBILE, pwd: PWD_HASH, captcha: '123456' }).catch(() => { });

    let login = await tryLogin(PWD_HASH);
    if (login.code !== 0) {
        login = await tryLogin('123456');
    }
    if (login.code !== 0) {
        // 再次尝试注册并用明文重试
        await httpReq('/user-service/user/register', 'POST', { mobile: MOBILE, pwd: '123456', captcha: '123456' }).catch(() => { });
        login = await tryLogin('123456');
    }
    if (login.code !== 0) {
        console.error('❌ 登录失败，响应=', login);
        throw new Error('登录失败');
    }
    const token = login.data.accessToken;

    console.log('🔌 连接WS...');
    const ws = new WebSocket(`ws://${HOST}:${PORT}/user-service/websocket?t=${token}`);
    await new Promise((resolve, reject) => { ws.on('open', resolve); ws.on('error', reject); setTimeout(() => reject(new Error('WS超时')), 10000); });

    ws.on('message', raw => { try { const m = JSON.parse(raw.toString()); if ([3, 4, 1009, 1119, 2016, 2030, 4439].includes(m.act_id)) console.log('📨', JSON.stringify(m)); } catch { } });

    function sendWait(filter, msg, label = '') {
        return new Promise((resolve) => {
            let to; const handler = (raw) => { try { const m = JSON.parse(raw.toString()); if (filter(m)) { clearTimeout(to); ws.removeListener('message', handler); resolve(m); } } catch { } };
            ws.on('message', handler); ws.send(JSON.stringify(msg)); to = setTimeout(() => { ws.removeListener('message', handler); console.log(`⏱ 超时: ${label}`); resolve(null); }, 8000);
        });
    }

    await new Promise(r => setTimeout(r, 1000));

    console.log('📋 查询角色列表(3)...');
    const listMsg = await sendWait(m => m.act_id === 3, { c: 3, d: null }, 'act_id=3');
    if (!listMsg || !Array.isArray(listMsg.roleList) || listMsg.roleList.length === 0) { console.log('❌ 无角色'); ws.close(); return; }
    const first = listMsg.roleList[0];
    console.log('🎯 选择角色(4):', first.id, first.name);
    const sel = await sendWait(m => m.act_id === 4, { c: 4, d: { characterId: first.id } }, 'act_id=4');
    if (!sel || sel.code !== 0) { console.log('❌ 选择角色失败'); ws.close(); return; }

    console.log('🧾 获取副将列表(1119)...');
    const listDep = await sendWait(m => m.act_id === 1119, { c: 1119, d: {} }, 'act_id=1119');
    if (!listDep || !listDep.list || listDep.list.length === 0) { console.log('❌ 无副将'); ws.close(); return; }
    const playerDeputyId = listDep.list[0].id; // player_deputy.id

    async function getDeputyDetail() {
        const detail = await sendWait(m => m.act_id === 1009, { c: 1009, d: { id: playerDeputyId } }, 'act_id=1009');
        return detail && detail.data ? detail.data : null;
    }

    let detail = await getDeputyDetail();
    if (!detail) { console.log('❌ 获取副将详情失败'); ws.close(); return; }
    console.log(`当前副将 等级=${detail.lvl}, 还需经验=${detail.exp}`);
    const dump = (d, tag) => {
        if (!d) return;
        console.log(`${tag} 属性: hp=${d.hp}, mp=${d.mp}, ap=${d.ap}, sp=${d.sp}; 点数: app=${d.app}, hpp=${d.hpp}, mpp=${d.mpp}, spp=${d.spp}, p=${d.p}`);
    };
    dump(detail, '➡️ 初始');

    // 先用经验书升到15级
    let guard = 200;
    while (detail.lvl < 15 && guard-- > 0) {
        const before2016 = await getDeputyDetail();
        const r2016 = await sendWait(m => m.act_id === 2016, { c: 2016, d: { gid: 83, cid: playerDeputyId } }, 'act_id=2016');
        if (!r2016 || r2016.code !== 0) { console.log('⚠️ 使用经验书失败或无书', r2016); break; }
        const after2016 = await getDeputyDetail();
        console.log('📈 经验书后 等级变化:', before2016?.lvl, '→', after2016?.lvl, '剩余经验:', after2016?.exp);
        dump(after2016, '📊 2016后');
        detail = after2016;
        if (!detail) break;
    }

    if (detail && detail.lvl >= 15) {
        console.log('🔎 2015 查询符合初级心法(147)的副将(应为11~40级)...');
        const r2015 = await sendWait(m => m.act_id === 2015, { c: 2015, d: { gid: 147, pageNum: 0 } }, 'act_id=2015');
        console.log('2015-147 响应(截取):', r2015 && r2015.list ? r2015.list.slice(0, 5) : r2015);

        console.log('📗 2030 使用初级心法(147) 2本并立即结算...');
        const before = await getDeputyDetail();
        dump(before, '📊 2030前');
        const r2030 = await sendWait(m => m.act_id === 2030, { c: 2030, d: { gid: 147, cid: playerDeputyId, c: 2 } }, 'act_id=2030');
        console.log('2030 响应:', r2030);
        const after = await getDeputyDetail();
        console.log(`✅ 2030后 等级=${after?.lvl}, 还需=${after?.exp} (前=${before?.lvl}/${before?.exp})`);
        dump(after, '📊 2030后');

        // 可选：4439 常人心法（若品质/名称允许）
        console.log('📘 4439 使用 3级常人心法(示例gid:304) 1本...');
        const before2 = await getDeputyDetail();
        const r4439 = await sendWait(m => m.act_id === 4439, { c: 4439, d: { gid: 304, cid: playerDeputyId, c: 1 } }, 'act_id=4439');
        console.log('4439 响应:', r4439);
        const after2 = await getDeputyDetail();
        console.log(`✅ 4439后 等级=${after2?.lvl}, 还需=${after2?.exp}`);
        dump(before2, '📊 4439前');
        dump(after2, '📊 4439后');
    } else {
        console.log('⚠️ 副将未达到15级，跳过2015/2030/4439');
    }

    ws.close();
}

main().catch(e => { console.error('执行失败:', e && e.message ? e.message : e); process.exit(1); });
